SPDX-FileCopyrightText: 2019 Ayman Ghazali SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
-- coding:Utf8 --
SOL Lewitt - Serial project no.1 - Configuration no.3 (MAIN CODE) # Authors: [Ayman Ghazali] # Date: [24.01.2020] # Blender version: [2.8 & hash] # OS: [MacOS Mojave (10.14.6] #
import bpy
import randomCleaning_Scene
Cleaning datafile through saving and reopening !!! only works if .blend file previously saved
def reset():helpers
    save = bpy.ops.wm.save_mainfile
    open = bpy.ops.wm.open_mainfile
    path = bpy.data.filepathaction
    if path is "":
        save()
        path = bpy.data.filepath
        print(".blend file saved in home directory")
    save(filepath=path)
    open(filepath=path)Delete scene before running script
def delete():helpers
    select = bpy.ops.object.select_all
    delete = bpy.ops.object.deleteaction
    select(action="SELECT")
    delete(use_global=False)
delete()                        Proximity/progression rule                             #
    This function generates a grid of dimensions (tuples) following the progressive rule used in Sol Lewitt’s art work
def gen_grid():All possible progressions
    poss = [
        [0, 1, 3, 1],
        [3, 1, 0, 1],
        [0, 1, 0, 1],
        [1, 0, 1, 3],
        [1, 0, 1, 0],
        [1, 3, 1, 0],
        [1, 3, 1, 3],
        [3, 1, 3, 1],
    ]
    random.shuffle(poss)
    i = poss[0][0]
    j = poss[0][1]
    k = poss[0][2]
    l = poss[0][3]
    r = random.choice([0, 1, 2, 3, 4, 5, 6, 7])
    a = poss[r][0]
    b = poss[r][1]
    c = poss[r][2]
    d = poss[r][3]The generated grid
    grid = [
        [(i, a), (i, b), (i, c), (i, d)],
        [(j, a), (j, b), (j, c), (j, d)],
        [(k, a), (k, b), (k, c), (k, d)],
        [(l, a), (l, b), (l, c), (l, d)],
    ]
    return grid
grid = gen_grid()
print("###############################################")
print(grid[0])
print(grid[1])
print(grid[2])
print(grid[3])
print("###############################################")                           Elements of variation                               #
    Initial variables
add_cube = bpy.ops.mesh.primitive_cube_add
x_sel = 0
y_sel = 0
z_sel = 0
factor = [4, 2, 1, 0.5]
S = False
W = TrueDefining the element of variation (The cube inside the cube)
This function defines the dimensional variations of the bigger geometry (Geometry 1)
def dim_element1(x_sel, y_sel, z_sel, h_sel1, h_sel2, Mat1, factor):Geometry 1
    add_cube(location=(x_sel, y_sel, z_sel))
    if Mat1 == True:
        bpy.ops.object.modifier_add(type="WIREFRAME")
        bpy.context.object.modifiers["Wireframe"].thickness = 0.3
        bpy.context.object.modifiers["Wireframe"].offset = -1
    bpy.ops.object.editmode_toggle()
    bpy.ops.transform.resize(value=(3 * factor, 3 * factor, h_sel1 * factor))
    add_cube(location=(x_sel, y_sel, z_sel))
    bpy.ops.transform.resize(value=(h_sel1 * factor, 3 * factor, 3 * factor))
    add_cube(location=(x_sel, y_sel, z_sel))
    bpy.ops.transform.resize(value=(3 * factor, h_sel1 * factor, 3 * factor))
    bpy.ops.object.editmode_toggle()This function defines the dimensional variations of the smaller gometry (Geometry 2)
def dim_element2(x_sel, y_sel, z_sel, h_sel1, h_sel2, Mat2, factor):Geometry 2
    add_cube(location=(x_sel, y_sel, z_sel))
    if Mat2 == True:
        bpy.ops.object.modifier_add(type="WIREFRAME")
        bpy.context.object.modifiers["Wireframe"].thickness = 0.3
        bpy.context.object.modifiers["Wireframe"].offset = -1
    bpy.ops.object.editmode_toggle()
    bpy.ops.transform.resize(value=(1 * factor, 1 * factor, h_sel2 * factor))
    add_cube(location=(x_sel, y_sel, z_sel))
    bpy.ops.transform.resize(value=(h_sel2 * factor, 1 * factor, 1 * factor))
    add_cube(location=(x_sel, y_sel, z_sel))
    bpy.ops.transform.resize(value=(1 * factor, h_sel2 * factor, 1 * factor))
    bpy.ops.object.editmode_toggle()This function creates the set of elements and makes them vary according to their position
def add_set(x_sel, y_sel, z_sel, tup, factor, Mat1, Mat2):Defining variables
    h_sel1 = tup[0]
    h_sel2 = tup[1]
    dim_element1(x_sel, y_sel, z_sel, h_sel1, h_sel2, Mat1, factor)
    dim_element2(x_sel, y_sel, z_sel, h_sel1, h_sel2, Mat2, factor)
dim = [4, 2, 1, 0.5]This function calculates the reccursive sequence that helps putting geometries with decreasing/increasing sizes next to eachother (sharing the same faces)
def term(n):    if n == 0:
        return 0
    else:
        res = term(n - 1) + (dim[n] + dim[n - 1]) / 2
        return resThis function Generates the 1/4 cube structure containing geometries placed according to Sol Lewitt’s rule and varying in 3 directional ways (x,y,z)
def generate_structure(locx, locy, locz, Mat1, Mat2):starting element :
    add_set(
        locx + 6 * (term(0) + 2),
        locy + 6 * dim[0] / 2,
        locz + 6 * dim[0] / 2,
        grid[1][1],
        dim[0],
        Mat1,
        Mat2,
    )resulting structure in x,y,z axes (Global) :
    add_set(
        locx + 6 * term(1) + 12,
        locy + 6 * dim[1] / 2,
        locz + 6 * dim[1] / 2,
        grid[1][2],
        dim[1],
        not Mat1,
        not Mat2,
    )
    add_set(
        locx + 6 * dim[1] / 2,
        locy + 6 * term(1) + 12,
        locz + 6 * dim[1] / 2,
        grid[2][1],
        dim[1],
        not Mat1,
        not Mat2,
    )
    add_set(
        locx + 6 * dim[1] / 2,
        locy + 6 * dim[1] / 2,
        locz + 6 * term(1) + 12,
        grid[2][2],
        dim[1],
        not Mat1,
        not Mat2,
    )resulting structure in x,y,z axes (local) : Alternatives in x :
    add_set(
        locx + 6 * term(2) + 12,
        locy + 6 * dim[2] / 2,
        locz + 6 * dim[2] / 2,
        grid[1][3],
        dim[2],
        Mat1,
        Mat2,
    )
    add_set(
        locx + 27,
        locy + 6 * dim[2] / 2,
        locz + term(2) + 10.5,
        grid[0][3],
        dim[2],
        Mat1,
        Mat2,
    )
    add_set(
        locx + 27,
        locy + term(2) + 10.5,
        locz + 6 * dim[2] / 2,
        grid[0][2],
        dim[2],
        Mat1,
        Mat2,
    )Alternatives in y :
    add_set(
        locx + 6 * dim[2] / 2,
        locy + 6 * term(2) + 12,
        locz + 6 * dim[2] / 2,
        grid[3][1],
        dim[2],
        Mat1,
        Mat2,
    )
    add_set(
        locx + 6 * dim[2] / 2,
        locy + 27,
        locz + term(2) + 10.5,
        grid[3][0],
        dim[2],
        Mat1,
        Mat2,
    )
    add_set(
        locx + term(2) + 10.5,
        locy + 27,
        locz + 6 * dim[2] / 2,
        grid[2][0],
        dim[2],
        Mat1,
        Mat2,
    )Alternatives in z :
    add_set(
        locx + 6 * dim[2] / 2,
        locy + 6 * dim[2] / 2,
        locz + 6 * term(2) + 12,
        grid[3][3],
        dim[2],
        Mat1,
        Mat2,
    )
    add_set(
        locx + term(2) + 10.5,
        locy + 6 * dim[2] / 2,
        locz + 27,
        grid[2][3],
        dim[2],
        Mat1,
        Mat2,
    )
    add_set(
        locx + 6 * dim[2] / 2,
        locy + term(2) + 10.5,
        locz + 27,
        grid[3][2],
        dim[2],
        Mat1,
        Mat2,
    )1/4 Cube structure (1)
generate_structure(0, 0, 0, W, S)1/4 Cube structure (2)
generate_structure(50, 0, 0, S, W)1/4 Cube structure (3)
generate_structure(100, 0, 0, S, S)1/4 Cube structure (4)
generate_structure(150, 0, 0, W, W)reset()